package com.junmoo.www.auth.config;

import com.junmoo.www.auth.module.system.service.SysMenuService;
import com.junmoo.www.auth.module.system.service.SysRoleService;
import com.junmoo.www.auth.module.system.service.SysUserService;
import com.junmoo.www.entity.SysMenu;
import com.junmoo.www.entity.SysRole;
import com.junmoo.www.entity.SysUser;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.ReactiveUserDetailsService;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;

import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;


@Slf4j
@Component
@AllArgsConstructor
public class CloudUserDetailsService  implements ReactiveUserDetailsService {
    private final SysMenuService sysMenuService;
    private final SysRoleService sysRoleService;
    private final SysUserService sysUserService;
    @Override
    public Mono<UserDetails> findByUsername(String username) {
        log.info("---UserDetailsService----;username:"+username);
        Set<GrantedAuthority> authorities = new LinkedHashSet<>();
        SysUser user = sysUserService.findOneByOr(new SysUser().setUsername(username));
        if(user==null) {
            return Mono.error(new Exception("查无此人"));
        }
        List<SysRole> roles = sysRoleService.findByUserId(user.getId());
        user.setRoles( roles.stream().collect(Collectors.toSet()) );
        user.setMenus( sysMenuService.findByUserId(user.getId()).stream().collect(Collectors.toSet()) );
        roles.forEach( role->{
            authorities.add( new SimpleGrantedAuthority("ROLE_"+role.getRoleCode()) );
            List<SysMenu> menus = sysMenuService.findByRoleId(role.getId());
            menus.forEach(menu->{
                authorities.add( new SimpleGrantedAuthority( menu.getMenuCode() ) );
            });
        } );
        user.setAuthorities(authorities);
        return Mono.just(user);
    }
}
